<template>
  <div class="loginDiv">
    <div class="msg">
      <div v-show="isMsg">
        <span>{{ msgText }}</span>
      </div>
    </div>
    <form>
      <table>
        <tbody>
          <tr>
            <td>
              <input type="text" placeholder="请输入用户名" v-model="username" autocomplete="off">
            </td>
          </tr>
          <tr>
            <td>
              <input type="password" placeholder="请输入密码" v-model="password" autocomplete="off">
            </td>
          </tr>
          <tr>
            <td class="code">
              <input type="text" placeholder="请输入验证码" v-model="code" autocomplete="off">
              <canvas ref="captchaCanvas" width="120" height="40" @click="generateCaptcha"></canvas>
            </td>
          </tr>
          <tr>
            <td>
              <input type="button" value="登录" @click="btnLogin">
            </td>
          </tr>
        </tbody>
      </table>
    </form>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'
import { jwtDecode } from "jwt-decode"
import { useUserStore } from '@/store/User.js'
import { useRouter } from 'vue-router'

const UserStore = useUserStore()
const router = useRouter()

// 定义响应式变量
let isMsg = ref(false)
let username = ref('')
let password = ref('')
let msgText = ref('')
let msgTimeout = null
let captchaCanvas = ref(null);
let captcha = ref('');
let code = ref('')

// 显示消息提示
const showMessage = (message) => {
  msgText.value = message
  isMsg.value = true
  if (msgTimeout) clearTimeout(msgTimeout) // 清除之前的计时器
  msgTimeout = setTimeout(() => {
    isMsg.value = false
  }, 3000)
}

// 清空输入框
const clearInputs = () => {
  username.value = ''
  password.value = ''
  code.value = ''
}

// 生成 4 位随机数字验证码
const generateCaptcha = () => {
  captcha.value = Math.floor(1000 + Math.random() * 9000).toString()
  drawCaptcha()
}

const drawCaptcha = () => {
  const canvas = captchaCanvas.value;
  const ctx = canvas.getContext('2d');

  // 清空画布
  ctx.clearRect(0, 0, canvas.width, canvas.height)

  // 设置背景颜色
  ctx.fillStyle = '#f0f0f0';
  ctx.fillRect(0, 0, canvas.width, canvas.height)

  // 绘制验证码文本
  ctx.font = '20px Arial'
  ctx.fillStyle = '#333'
  ctx.textBaseline = 'middle'
  ctx.textAlign = 'center'

  // 随机位置绘制每个字符
  for (let i = 0; i < captcha.value.length; i++) {
    const angle = Math.random() - 0.5
    const x = (canvas.width / 5) * (i + 1)
    const y = canvas.height / 2
    ctx.translate(x, y)
    ctx.rotate(angle)
    ctx.fillText(captcha.value[i], 0, 0)
    ctx.rotate(-angle)
    ctx.translate(-x, -y)
  }

  // 绘制干扰线
  for (let i = 0; i < 5; i++) {
    ctx.strokeStyle = '#cccccc'
    ctx.beginPath()
    ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height)
    ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height)
    ctx.stroke()
  }

  // 绘制干扰点
  for (let i = 0; i < 30; i++) {
    ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'
    ctx.beginPath()
    ctx.arc(Math.random() * canvas.width, Math.random() * canvas.height, 1, 0, Math.PI * 2)
    ctx.fill()
  }
}

// 登录逻辑
const btnLogin = () => {
  if (username.value.trim() === '' || password.value.trim() === '') {
    showMessage('用户名或密码不能为空')
    return
  }

  if (!(captcha.value === code.value)) {
    showMessage('请输入正确的验证码')
    generateCaptcha()
    code.value = ''
    return
  }

  axios({
    method: 'post',
    url: 'http://127.0.0.1:8000/api/users/login',
    data: {
      username: username.value,
      password: password.value
    }
  })
    .then(res => {
      // 解析 Token
      const { userId, username } = jwtDecode(res.data.token);
      UserStore.setUser(userId, username)
      generateCaptcha()
      router.push({
        path: '/'
      })
    })
    .catch(err => {
      showMessage(err.response.data.message)
    })
  clearInputs()
}

onMounted(() => {
  generateCaptcha()
})

defineExpose({
  clearInputs, generateCaptcha
})
</script>

<style scoped>
.loginDiv {
  width: 80%;
  height: 50%;
  margin: 30px auto;
}

.msg {
  height: 40px;
}

.msg>div {
  width: 90%;
  margin: 0 auto;
  line-height: 30px;
  background-color: rgba(255, 0, 0, 0.33);
  border: 1px solid rgb(255, 0, 0);
  color: red;
}

table,
tbody,
td {
  width: 100%;
}

table {
  margin-top: 20px;
}

td {
  height: 80px;
}

form input {
  width: 90%;
  height: 40px;
}

form .code {
  display: flex;
  justify-content: center;
  align-items: center;
}

form canvas {
  width: 30%;
  height: 40px;
  border: 1px solid;
  cursor: pointer;
}

form [placeholder="请输入验证码"] {
  width: 55%;
  margin-right: 5%;
}

form [type="text"],
form [type="password"] {
  text-indent: 20px;
  transition: all 0.5s;
  outline: none;
  border-radius: 5px;
}

form [type="text"]:focus,
form [type="password"]:focus {
  border: 10px solid rgb(175, 183, 255);
}

form [type="text"]:not(:focus),
form [type="password"]:not(:focus) {
  border: 1px solid rgb(0, 26, 255);
}

form [value="登录"] {
  background-color: rgba(0, 183, 255, 0.293);
  border-radius: 5px;
  border: 2px solid blue;
  color: white;
  font-size: 18px;
  cursor: pointer;
}

form [value="登录"]:hover {
  background-color: rgba(102, 0, 255, 0.308);
  color: rgb(0, 4, 255);
}
</style>